from django.forms                       import BaseForm
from sitepal.sitemenu.actions.actions   import ACTION_SUBMIT_FORM
from sitepal.sitemenu.actions.base_view import BaseView

class FormView(BaseView):
    def __init__(self,form_class,submit_handler,post_submit_redirect,
                 cancel_submit_redirect,apply_to_form=None,form_prefix=None,**kwargs):
        assert issubclass(form_class,BaseForm)
        assert callable(submit_handler)
        if 'template_object_name' not in kwargs:
            kwargs['template_object_name'] = 'form'
        BaseView.__init__(self,**kwargs)
        self._form_class             = form_class
        self._submit_handler         = submit_handler
        self._post_submit_redirect   = post_submit_redirect
        self._cancel_submit_redirect = cancel_submit_redirect
        self._apply_to_form          = apply_to_form
        self._form_prefix            = form_prefix

    def get_context(self,request,obj,**kwargs):
        context                = BaseView.get_context(self,request,obj,**kwargs)
        context['form_action'] = request.path
        return context

    def get_form(self,request,**kwargs):
        from sitepal.sitemenu.actions import Http403
        
        if not self.has_perm(ACTION_SUBMIT_FORM,request.user):
            raise Http403
        if callable(self._form_prefix):
            prefix = self._form_prefix(self,request,**kwargs)
        else:
            prefix = self._form_prefix
        if request.method == 'POST':
            form = self._form_class(data=request.POST,files=request.FILES,prefix=prefix)
        elif request.method == 'GET':
            form = self._form_class(prefix=prefix)
        else:
            return HttpResponseServerError
        if self._apply_to_form:
            self._apply_to_form(self,request,form)
        return form

    def handle_submit(self,request,form,**kwargs):
        self._submit_handler(request,form,**kwargs)

    def handle_get(self,request,**kwargs):
        form    = self.get_form(request,**kwargs)
        context = self.get_context(request,form)
        return self.response(request,context)

    def handle_post(self,request,**kwargs):
        if 'cancel' in request.POST:
            return self.cancel_submit_redirect(request)
        form = self.get_form(request,**kwargs)
        if form.is_valid():
            try:
                self.handle_submit(request,form,**kwargs)
                return self.post_submit_redirect(request,form)
            except:
                pass
        context = self.get_context(request,form)
        return self.response(request,context)

    def post_submit_redirect(self,request,obj):
        return self.redirect(self._post_submit_redirect,request,obj)

    def cancel_submit_redirect(self,request):
        return self.redirect(self._cancel_submit_redirect,request,None)

